package freezzz.client;

import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;

import java.util.Date;
import java.util.HashMap;


@SuppressWarnings( { "ALL" } )
public class TimeLine extends SimplePanel {
    static final int NUMSLIDES = 9;
    private final int SLIDE_WIDTH = 97;
    private final int SLIDE_HEIGHT = 150;

    private HorizontalPanel horizontalPanel;
    private Date currentDate;

    private SimplePanel mover = new SimplePanel ();
    private boolean dragging = false;
    int dragStartX;

    private int stabilazingdirection = 0;
    private int queueLeft = 0;
    private int queueRight = 0;

    private HashMap<Date, Slide> slidesCache = new HashMap<Date, Slide> ();

    public TimeLine () {
        currentDate = Utils.getDayDate ( new Date () );

        currentDate.setDate ( currentDate.getDate () - NUMSLIDES );
        horizontalPanel = new HorizontalPanel ();
        horizontalPanel.setStyleName ( "timeline-table" );
        getElement ().setClassName ( "timeline" );
        add ( horizontalPanel );
        System.currentTimeMillis ()
        mover.setStylePrimaryName ( "mover" );
        mover.add ( new Label ( "" ) );
        horizontalPanel.add ( mover );
        // Populate first slides

        for ( int i = 0; i < NUMSLIDES; i++ ) {
            currentDate.setDate ( currentDate.getDate () + 1 );
            Slide tmpSlide = new Slide ( currentDate );
            slidesCache.put ( currentDate, tmpSlide );
            horizontalPanel.add ( tmpSlide );
        }
        currentDate = Utils.getDayDate ( new Date () );
        this.sinkEvents ( Event.MOUSEEVENTS );
    }

    @Override
    public void onBrowserEvent ( Event event ) {
        if ( event.getTypeInt () == Event.ONMOUSEDOWN ) {
            dragging = true;
            stabilazingdirection = 0;
            mover.setPixelSize ( SLIDE_WIDTH, SLIDE_HEIGHT );
            dragStartX = event.getClientX ();
        }
        if ( event.getTypeInt () == Event.ONMOUSEMOVE && dragging ) {
            int delta = dragStartX - event.getClientX ();

            if ( delta < -1*(SLIDE_WIDTH-1) ) {
                // mouse ->>>>>
                // newslide x[   ]
                insertLeftInstant ();
                dragStartX = event.getClientX ();
                return;
            }
            if ( delta > (SLIDE_WIDTH-1) ) {
                // mouse <<<<<<-
                // newslide [   ]x
                insertRightInstant ();
                dragStartX = event.getClientX ();
                return;
            }

            if ( delta <= 0 ) {
                delta = SLIDE_WIDTH + ( -1 * delta );
            } else {
                delta = SLIDE_WIDTH - delta;
            }

            mover.setPixelSize ( delta, mover.getElement ().getClientHeight () );
        }

        if ( event.getTypeInt () == Event.ONMOUSEUP && dragging ) {

            dragging = false;
            if ( mover.getElement ().getClientWidth () == SLIDE_WIDTH ) return;
            if ( ( mover.getElement ().getClientWidth () >= SLIDE_WIDTH ) ) stabilazingdirection = 1;
            else stabilazingdirection = -1;
            new Timer() {
                public void run () {
                    if ( stabilazingdirection == 0 ) {
                        cancel ();
                    }
                    int currentiwdth = mover.getElement ().getClientWidth ();

                    if ( stabilazingdirection == 1 && currentiwdth < (SLIDE_WIDTH*2) || stabilazingdirection == -1 && currentiwdth > 1 ) {
                        currentiwdth += stabilazingdirection;
                        mover.setPixelSize ( currentiwdth, SLIDE_HEIGHT );

                    } else {
                        if ( stabilazingdirection == 1 ) insertLeftInstant ();
                        else insertRightInstant ();
                        stabilazingdirection = 0;
                        cancel ();
                    }
                }
            }.scheduleRepeating ( 1 );
        }
    }

    public void scrollLeft () {
        queueLeft++;
        Date tmpDate = Utils.getDayDate ( currentDate );
        tmpDate.setDate ( currentDate.getDate () - NUMSLIDES );
        currentDate.setDate ( currentDate.getDate () - 1 );
        Slide tmpSlide;
        if ( slidesCache.containsKey ( tmpDate ) ) {
            tmpSlide = slidesCache.get ( tmpDate );
        } else {
            tmpSlide = new Slide ( tmpDate );
            slidesCache.put ( tmpDate, tmpSlide );
        }

        mover.setPixelSize ( 0, SLIDE_HEIGHT );
        horizontalPanel.insert ( tmpSlide, 1 );
        new Timer() {
            int width = 0;

            public void run () {
                mover.setPixelSize ( width, SLIDE_HEIGHT );
                width += ( 5 * queueLeft );
                if ( width > SLIDE_WIDTH ) {
                    horizontalPanel.remove ( horizontalPanel.getWidgetCount () - 1 );
                    mover.setPixelSize ( SLIDE_WIDTH, SLIDE_HEIGHT );
                    cancel ();
                    queueLeft--;
                }
            }
        }.scheduleRepeating ( 10 );


    }

    public void scrollRight () {
        currentDate.setDate ( currentDate.getDate () + 1 );
        Slide tmpSlide;
        if ( slidesCache.containsKey ( currentDate ) ) {
            tmpSlide = slidesCache.get ( currentDate );
        } else {
            tmpSlide = new Slide ( currentDate );
            slidesCache.put ( currentDate, tmpSlide );
        }
        horizontalPanel.insert ( tmpSlide, horizontalPanel.getWidgetCount () );

        new Timer() {
            int width = SLIDE_WIDTH;

            public void run () {
                mover.setPixelSize ( width, SLIDE_WIDTH );
                width -= 5;
                if ( width < 1 ) {
                    horizontalPanel.remove ( 1 );
                    mover.setPixelSize ( SLIDE_WIDTH, SLIDE_HEIGHT );
                    cancel ();
                }
            }
        }.scheduleRepeating ( 10 );
    }

    public void insertLeftInstant () {
        Date tmpDate = Utils.getDayDate ( currentDate );
        tmpDate.setDate ( currentDate.getDate () - NUMSLIDES );
        currentDate.setDate ( currentDate.getDate () - 1 );
        Slide tmpSlide;
        if ( slidesCache.containsKey ( tmpDate ) ) {
            tmpSlide = slidesCache.get ( tmpDate );
        } else {
            tmpSlide = new Slide ( tmpDate );
            slidesCache.put ( tmpDate, tmpSlide );
        }
        horizontalPanel.insert ( tmpSlide, 1 );
        horizontalPanel.remove ( horizontalPanel.getWidgetCount () - 1 );
        mover.setPixelSize ( SLIDE_WIDTH, SLIDE_HEIGHT );
    }

    public void insertRightInstant () {
        currentDate.setDate ( currentDate.getDate () + 1 );
        Slide tmpSlide;
        if ( slidesCache.containsKey ( currentDate ) ) {
            tmpSlide = slidesCache.get ( currentDate );
        } else {
            tmpSlide = new Slide ( currentDate );
            slidesCache.put ( currentDate, tmpSlide );
        }
        horizontalPanel.insert ( tmpSlide, horizontalPanel.getWidgetCount () );
        horizontalPanel.remove ( 1 );
        mover.setPixelSize ( SLIDE_WIDTH, SLIDE_HEIGHT );
    }

    public void addSlide ( Slide slide ) {
        horizontalPanel.add ( slide );
    }

}
